﻿using System;
using System.Text;
using System.IO;

using System.Diagnostics;

using System.Threading;
using System.Threading.Tasks;

namespace Pixcom
{
    public class Logger
    {
        private const string PATH = "Log";
        private const string FILE_NAME = "Logs.txt";
        private const string FULL_NAME = PATH + "/" + FILE_NAME;
        public static readonly object Locker = new object();
        private static StreamWriter WRITER;
        private static string GUID;
     

        private static string ContinueWriteCaches;
        private static readonly Stopwatch Continue_WriteSw;
        private static int ContinueTime = 300; // 300毫秒以后，连续写操作，都统一到一块操作
        private static int ContinueCountMax = 100; // 当连续写操作次数上限到指定的数值后，都写一次操作，之后的重新再计算
        private static int ContinueCount = 0;
        public static int AllWriteCount = 0;
       
        static Logger()
        {
            Continue_WriteSw = new Stopwatch();
        }

        private static string ProjectFullName
        {
            get
            {
               
                if (!string.IsNullOrEmpty(Properties.Settings.Default.AppName))
                    return PATH +"/"+ Properties.Settings.Default.AppName+"_"+ FILE_NAME;
                if (string.IsNullOrEmpty(GUID))
                    GUID = Guid.NewGuid().ToString();
                return PATH + "/" + "TEMPLATE_" + GUID + "_" + FILE_NAME;
            }
        }

        private static void Write(string msg)
        {
            if (string.IsNullOrEmpty(msg)) return;
            msg += "\r\n";
            lock (Locker)
            {
                if (Continue_WriteSw.IsRunning && Continue_WriteSw.ElapsedMilliseconds < ContinueTime)
                {
                    if (ContinueWriteCaches == null) ContinueWriteCaches = msg;
                    else ContinueWriteCaches += msg;// +"\r\n";
                    ContinueCount++;
                    if (ContinueCount > ContinueCountMax)
                    {
                        _Write();
                    }
                    return;
                }

                if (!Continue_WriteSw.IsRunning) Continue_WriteSw.Start();
                ContinueWriteCaches = msg;
                
                new Task(() =>
                {
                    Thread.Sleep(ContinueTime);
                    _Write();
                }).Start();
            }
        }

        private static void _Write()
        {
            try
            {
                if (ContinueWriteCaches != null)
                {
                    if (!File.Exists(ProjectFullName))
                    {
                        if (!Directory.Exists(PATH))
                            Directory.CreateDirectory(PATH);
                        //File.Create(ProjectFullName);
                    }
                    //查看文件大小 
                    System.IO.FileInfo fileInfo    = new System.IO.FileInfo(ProjectFullName);
                    if (fileInfo.Length > 1024 * 1024 * 10)//10M
                    {
                        fileInfo.MoveTo(ProjectFullName.Replace(".",DateTime.Now.ToString("_yyyyMMddHHmmss_ffff.")));
                    }

                    WRITER = new StreamWriter(ProjectFullName, true, Encoding.UTF8);
                    WRITER.WriteLine(ContinueWriteCaches);
                    WRITER.Flush();
                    WRITER.Close();
                }
                Continue_WriteSw.Stop();
                Continue_WriteSw.Reset();
                ContinueWriteCaches = null;
                ContinueCount = 0;

                Interlocked.Increment(ref AllWriteCount);
            }
            catch (Exception)
            {

               
            }
        }
        public static void Debug(String format, params object[] args) {
              String  msg =      string.Format(format, args);
               Debug(msg);
        }

        public static void Debug(string msg)
        {
            msg = string.Format("[{0}] |{1,5} : {2}", DateTime.Now.ToString(PicProtocal.TIMSTR), "Deb",   msg);
            Write(msg);
        }
        public static void Info(String format, params object[] args)
        {
            String msg = string.Format(format, args);
            Info(msg);
        }
        public static void Info(string msg)
        {
            msg = string.Format("[{0}] |{1,5} : {2}", DateTime.Now.ToString(PicProtocal.TIMSTR), "Inf",  msg);
            Write(msg);
        }
        public static void Error(String format, params object[] args)
        {
            String msg = string.Format(format, args);
            Error(msg);
        }
        public static void Error(string msg)
        {
            msg = string.Format("[{0}] |{1,5} : {2}", DateTime.Now.ToString(PicProtocal.TIMSTR), "Err", msg);
            Write(msg);
        }
    }
}